package com.etc.reflect;

import com.example.springboot0.aspect.Log;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.stream.Stream;

public class TestMain3 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        // 获取反射对象的三种方式
        // 类名.clss
        Class stuclass1 = Student.class;
        // 对象.getClass();
        Student student = new Student();
        Class stuclass2 = student.getClass();
        // Class.forName("类全名")
        try {
            Class stuclass3 = Class.forName("com.etc.reflect.Student");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        Constructor c1 = stuclass1.getDeclaredConstructor();
        System.out.println(c1);

        Constructor c2 = stuclass1.getDeclaredConstructor(new Class[]{String.class, int.class});
        System.out.println(c2);

//        Student stu2 = new Student("tom", 1);

        Student stu3 = (Student) c2.newInstance(new Object[]{"tom", 1});
        System.out.println(stu3.getSno() + "" + stu3.getName());

        Stream.of(stuclass1.getDeclaredFields()).forEach(System.out::println);
//        Stream.of(stuclass1.getFields()).forEach(System.out::println);
        Field field = stuclass1.getDeclaredField("name");

        // 私有的属性访问
        field.setAccessible(true);
        field.set(stu3,"jerrry");
        System.out.println(stu3.getSno() + "" + stu3.getName());

        Stream.of( stuclass1.getDeclaredMethods()).forEach(System.out::println);
        System.out.println("---------------------");
        Stream.of( stuclass1.getMethods()).forEach(System.out::println);
        System.out.println("---------------------");

        Method method = stuclass1.getMethod("study", new Class[]{String.class});
        // 执行方法 stu3.study("java")
        method.invoke(stu3, "java"); // new Object[]{"java"}

        Stream.of(method.getDeclaredAnnotations()).forEach(item -> {
//            System.out.println(item);
            if (item instanceof Log) {
                System.out.println(((Log) item).value());
            }
        });
    }
}
